package user

import (
	"common/checkImg"
	"common/jwt"
	"common/md5"
	"common/models"
	"common/validate"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"go.uber.org/zap"
	"strconv"
	"time"
	"video/pkg/dao/redis"
)

// Login 用户登录
// @Summary 用户登录
// @Description 验证码-用户登录
// @Tags 用户
// @Accept application/json
// @Produce application/json
// @Param object body docModel.DocUserLoginReq false "登录参数"
// @Security ApiKeyAuth
// @Success 200 {object} docModel.DocResp
// @Router /user/login [post]
func (h UHandler) Login(c *gin.Context) {
	req := new(models.UserLoginReq)
	resp := new(models.RespData)
	login := new(models.UserLoginResp)
	if err := c.ShouldBindJSON(req); err != nil {
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			zap.L().Error("User:Login with invalid fail", zap.Error(err))
			resp.SendServerBusy(c)
			return
		} else {
			zap.L().Error("User:Login with invalid fail", zap.Error(errs))
			resp.SendCodeWithMsg(c, models.CodeInvalidParam, validate.RemoveTopStruct(errs.Translate(validate.Trans)))
			return
		}
	}
	//校验验证码
	verify := checkImg.Verify(req.SearchId, req.CheckCode, h.R)
	if !verify {
		resp.SendCode(c, models.CodeImageValidationErr)
		return
	}
	//用户存在否
	exist, err := h.M.CheckUsernameExist(req.Username)
	if err != nil {
		zap.L().Error("User:h.M.CheckUsernameExist error", zap.Error(err))
		resp.SendServerBusy(c)
		return
	}
	if !exist {
		resp.SendCode(c, models.CodeUserNotExist)
		return
	}
	//校验正确性
	userInfo, err := h.M.QueryUserInfoByUsername(req.Username)
	if err != nil {
		zap.L().Error("User:h.M.QueryUserInfoByUsername error", zap.Error(err))
		resp.SendServerBusy(c)
		return
	}
	if !md5.Compare(userInfo.Password, req.Password) {
		resp.SendCode(c, models.CodeInvalidPassword)
		return
	}
	token, err := jwt.GenToken(userInfo.ID, userInfo.UserId, userInfo.NickName)
	if err != nil {
		zap.L().Error("User:jwt.GenToken error", zap.Error(err))
		resp.SendServerBusy(c)
		return
	}
	//存储uid -ID
	idStr := strconv.Itoa(int(userInfo.ID))
	if err := h.R.SetString(redis.UserId+userInfo.UserId, idStr, 2*time.Hour); err != nil {
		zap.L().Error("User: h.R.SetString error", zap.Error(err))
		resp.SendServerBusy(c)
		return
	}
	login.NickName = userInfo.NickName
	login.Token = token
	login.UserId = userInfo.UserId
	resp.Data = login
	resp.SendSuccess(c)
}
